import tkinter
from tkinter import Frame,messagebox
from PIL import Image, ImageTk
import numpy as np
import threading
import time


class Application(Frame):
    def __init__(self, width,height,lip_prediction_model,
                 leap_prediction_model,speech_prediction_model,
                 all_prediction_model,master=None):
        super(Application,self).__init__(master)
        self.pack(expand=tkinter.YES, fill=tkinter.BOTH)
        self.windowInit(width,height)
        self.createWidgets()

        self._lip_model=lip_prediction_model
        self._leap_model=leap_prediction_model
        self._speech_model=speech_prediction_model
        self._all_model=all_prediction_model
        self.flag=0
        self.is_run=True
        self._mutex = threading.Lock()      # 线程锁

    def windowInit(self,width,height):
        self.master.title('welcome to distinguish system')
        # self.master.bg = 'black'
        self.master.geometry("{}x{}".format(width, height))

    def _updateButtonColour(self, curr_button, buttons, flag):
        # 更改按钮颜色
        curr_button["bg"] = "blue"
        for button in buttons:
            button["bg"] = "white"
        self.flag = flag   # 设置运行类型

    def _initButtonColour(self,buttons):
        for button in buttons:
            button["bg"] = "white"
        self.flag = 0  # 设置运行类型

    def createWidgets(self):
        # frame1 标题
        fm1 = Frame(self)
        titleLabel = tkinter.Label(fm1,text="Distinguish System",
                                   font=('微软雅黑',20),fg = 'black')
        titleLabel.pack()
        fm1.pack(side=tkinter.TOP,expand=tkinter.YES,
                 fill='x',pady=3)

        # frame2 功能按钮
        fm2 = Frame(self)
        fm2_left = Frame(fm2)
        fm2_right = Frame(fm2)
        fm2_left_top = Frame(fm2_left)
        fm2_left_bottom = Frame(fm2_left)

        self._buttom_lip=tkinter.Button(
            fm2_left_top,text="唇形",
            font=('微软雅黑',15),bg="white",
            command=lambda: self._updateButtonColour(self._buttom_lip,
                                              (self._buttom_speech,self._buttom_gesture,self._buttom_all),
                                               flag=1))
        self._buttom_lip.pack(side=tkinter.LEFT)
        self._buttom_speech=tkinter.Button(
            fm2_left_top,text="语音",
            font=('微软雅黑',15),bg="white",
            command=lambda: self._updateButtonColour(self._buttom_speech,
                                              (self._buttom_lip, self._buttom_gesture, self._buttom_all),
                                               flag=2))
        self._buttom_speech.pack(side=tkinter.LEFT,
                                 fill="y",padx=20)
        fm2_left_top.pack(side=tkinter.TOP,
                          fill="x")

        self._buttom_gesture=tkinter.Button(
            fm2_left_bottom,text="手势",
            font=('微软雅黑',15),bg="white",
            command=lambda: self._updateButtonColour(self._buttom_gesture,
                                              (self._buttom_lip, self._buttom_speech, self._buttom_all),
                                               flag=3))
        self._buttom_gesture.pack(side=tkinter.LEFT)
        self._buttom_all=tkinter.Button(
            fm2_left_bottom,text="综合",
            font=('微软雅黑',15),bg="white",
            command=lambda: self._updateButtonColour(self._buttom_all,
                                               (self._buttom_lip, self._buttom_speech, self._buttom_gesture),
                                               flag=4))
        self._buttom_all.pack(side=tkinter.LEFT,
                              fill="y",padx=20)
        fm2_left_bottom.pack(side=tkinter.TOP,
                             fill="x",pady=3)
        fm2_left.pack(side=tkinter.LEFT,
                      expand=tkinter.YES,
                      fill="x",padx=20)

        button_run = tkinter.Button(fm2_right, text='运行',
                                    font=('微软雅黑',15),bg="white",
                                    command=self._startupProgram)
        button_run.pack(side=tkinter.LEFT,padx=10)
        buttom_exit=tkinter.Button(fm2_right,text="中止",
                                   font=('微软雅黑',15),bg="white",
                                   command=self.breakSystem)
        buttom_exit.pack(side=tkinter.LEFT)
        fm2_right.pack(side=tkinter.RIGHT)
        fm2.pack(side=tkinter.TOP, expand=tkinter.TRUE)

        # frame3 预测框
        fm3=Frame(self)
        predict_label=tkinter.Label(fm3,text="预测指令：",
                                    font=('微软雅黑',15))
        predict_label.pack(side=tkinter.LEFT,
                           padx=10)
        self.predict_text=tkinter.Entry(fm3,font=('微软雅黑',15),width=10)
        self.predict_text.pack(side=tkinter.LEFT)
        fm3.pack(side=tkinter.TOP,expand=tkinter.TRUE,
                 pady=10)

        # fm4 显示视频
        fm4 = Frame(self)
        load=np.full(shape=(375,500,3),fill_value=255,
                     dtype=np.uint8)
        load=Image.fromarray(load)
        reader = ImageTk.PhotoImage(load)
        self.panel = tkinter.Label(fm4, image=reader)
        self.panel.image = reader
        self.panel.pack()
        fm4.pack(side=tkinter.TOP)

    def _startupProgram(self):
        # 调用相应的检测程序
        if self.flag==0:
            messagebox.showinfo(title="提示", message="请选择检测类型！")
            return None

        # 唇语识别
        elif self.flag==1:
            child_thread = threading.Thread(target=self._lip_model.run,
                                            args=(self, 0))
            child_thread.start()

        elif self.flag==2:
            child_thread = threading.Thread(target=self._speech_model.run,
                                            args=(self,))
            child_thread.start()

        # 手势识别
        elif self.flag==3:
            child_thread = threading.Thread(target=self._leap_model.run,
                                            args=(self,))
            child_thread.start()

        elif self.flag==4:
            self.initOutputVariable()
            self._all_model.run(self)

    def outputPredictWord(self,word):            
        self.predict_text.delete(0,tkinter.END)
        self.predict_text.insert(0,word)

    def breakSystem(self):
        # 退出功能模块
        if self.flag==0:
            pass

        else:
            self._mutex.acquire()
            self.is_run=False
            self._mutex.release()
            self.outputPredictWord("")
            self._initButtonColour([self._buttom_lip,self._buttom_speech,
                                    self._buttom_gesture,self._buttom_all])

    def initOutputVariable(self):
        self._lip_output_word_prob=[None,0]
        self._leap_output_word_prob=[None,0]
        self._speech_output_word_prob=[None,0]

    def judge(self,variable_one,variable_two,variable_three, word, prob):
        variable_one[0], variable_one[1] = word, prob

        self._mutex.acquire()
        if variable_two[0] and variable_three[0]:
            pass
        elif variable_two[0]:
            pass
        elif variable_three[0]:
            pass
        else:
            self.outputPredictWord(variable_one[0])
        variable_one[0], variable_one[1] = None, 0
        self._mutex.release()

    def outputAllPredictWord(self,word,prob,flag):
        # if flag==1:
        #     self.judge(self._lip_output_word_prob,
        #                self._leap_output_word_prob,
        #                self._speech_output_word_prob,
        #                word,prob)
        # elif flag==2:
        #     self.judge(self._speech_output_word_prob,
        #                self._lip_output_word_prob,
        #                self._leap_output_word_prob,
        #                word,prob)
        # elif flag==3:
        #     self.judge(self._leap_output_word_prob,
        #                self._speech_output_word_prob,
        #                self._lip_output_word_prob,
        #                word,prob)

        # 最大概率
        if flag==1:
            self._lip_output_word_prob[0],self._lip_output_word_prob[1]=word, prob
        elif flag==2:
            self._speech_output_word_prob[0],self._speech_output_word_prob[1]=word, prob
        elif flag==3:
            self._leap_output_word_prob[0], self._leap_output_word_prob[1]=word, prob

        max_prob_index=np.argmax(np.array([self._lip_output_word_prob[1],
                                           self._speech_output_word_prob[1],
                                           self._leap_output_word_prob[1]]))
        if max_prob_index==0:
            self.outputPredictWord(self._lip_output_word_prob[0])
        elif max_prob_index==1:
            self.outputPredictWord(self._speech_output_word_prob[0])
        elif max_prob_index==2:
            self.outputPredictWord(self._leap_output_word_prob[0])
        self.initOutputVariable()